package cn.tedu.charging.order.rabbit;
import cn.tedu.charging.order.config.RabbitConfiguration;
import cn.tedu.charging.order.dao.mapper.repository.OrderRepository;
import cn.tedu.charging.order.pojo.po.OrderMQPO;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @Author: Miyako
 * @CreateTime: 2024-10-21  00:41
 * @Description: 消费者
 */
@Slf4j
@Component
public class RabbitMQDeadLetterConsumer {

    @Autowired
    OrderRepository orderRepository;

    /**
     * @param: 订单号
     * @return: void
     * @description:
     * 消费死信队列的信息
     * 通过订单号去成功订单查询
     **/
    @RabbitListener(queues = RabbitConfiguration.DEAD_LETTER_QUEUE_NAME )
    public void consumeChargingQueue(OrderMQPO orderMQPO , Message message , Channel channel) throws IOException {
        //先去成功里查询


        //更新状态充电中为异常结束
        Integer number = orderRepository.UpdateOrderStatusPtoE(orderMQPO.getOrderNo());



        //消息队列中的ack
        //RabbitMQOrderDeadLetterConsumer 消息者 通过 consumeChargingQueue
        //消费死信队列 DEAD_LETTER_QUEUE_NAME,处理业务,更新订单状态

        // 正常情况 自动ack 默认
        // 更新订单状态 updateOrderStatusFromProcessToExceptionEnd
        // 消费者自动 给 RabbitMQ 返回一个响应 ack 消费者告诉RabbitMQ 消息消费成功了
        // RabbitMQ 收到ack后,会认为消费者消费成功了,RabbitMQ会把这条消息从队列中删除

        // 异常情况 更新订单状态,数据库出现异常,更新失败,消费者抛异常,
        // 如果是自动ack 消费者 自动(不管消费者是否有异常) 给 RabbitMQ 返回一个响应 ack
        // RabbitMQ 收到ack后,会认为消费者消费成功了,RabbitMQ会把这条消息从队列中删除

        //消息没有被成功的消费,而且还被RabbitMQ 删除 消息丢失了,超时订单没有被正确的处理

        //手动ack 需要通过代码的方式 告诉 rabbitMq
        //配置文件ack 改为手动方式
        //spring.rabbitmq.listener.direct.acknowledge-mode=manual
        //把下面的两行代码注释掉,updateOrderStatusFromProcessToExceptionEnd执行完
        //消息会一直在rabbitMQ的队列里,不会被删除


        long deliveryTag = message.getMessageProperties().getDeliveryTag();

        channel.basicAck(deliveryTag,true);


        log.debug("修改了订单{},影响了{}条记录",orderMQPO,number);



    }
}
